package main

import (
	"fmt"
	"sync"
)
var wg sync.WaitGroup

func putNum(intChan chan int){
	for i := 2; i < 1000; i++ {
		intChan <- i
	}
	close(intChan)
	wg.Done()
}

func primeNum(intChan chan int, primeChan chan int, exitChan chan bool){
	for num := range intChan {
		var flag bool = true
		for i := 2; i < num; i++ {
			if num%i == 0 {
				flag = false
				break
			}
		}
		if flag { 
			primeChan <- num //num是素数
		}
	}
	// close(primeChan) // 如果一个channel关闭了，就没法给这个channel
	wg.Done()

// 给exitChan发送一个信号，表示primeChan关闭了
	exitChan <- true
}

func printPrime(primeChan chan int){
	for num := range primeChan {
		fmt.Println(num)
	}
	wg.Done()
}

func main() {
	intChan := make(chan int, 1000) //存放数字
	primeChan := make(chan int, 1000) //存放素数 (注意：这里的容量是1000，可以根据需要调整) 如果不设置容量，则默认是无限容量
	exitChan := make(chan bool, 16) //表示primeChan关闭了

	// 放入数字的协程
  wg.Add(1)
	go putNum(intChan)

	for i := 0; i < 16; i++ {
		wg.Add(1)
		// 统计素数的协程
		go primeNum(intChan, primeChan, exitChan)
	}

	wg.Add(1)
	// 打印素数的协程
	go printPrime(primeChan)

	wg.Add(1)
	// 判断exitChan是否存满
	go func() {
		for i := 0; i < 16; i++ {
			<- exitChan
		}
		close(primeChan) // 关闭primeChan
		wg.Done()
	}()

	wg.Wait()
	fmt.Println("结束")
}